package hibernate.method;

import hibernate.method.interfaces.RelationMethodsInterface;
import hibernate.model.Relation;
import hibernate.model.User;

import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.LogicalExpression;
import org.hibernate.criterion.Restrictions;

public class RelationMethods implements RelationMethodsInterface{

	@Override
	public void addRelation(SessionFactory sessionFactory, Session session,
			int inviting, int invited) {
		Relation relation = new Relation();
		relation.setInviting(inviting);
		relation.setInvited(invited);
		session.save(relation);
	}

	@Override
	public void deleteRelation(SessionFactory sessionFactory, Session session,
			Relation relation) {
		session.delete(relation);
		
	}

	@Override
	public List<User> findRelationByFrom(SessionFactory sessionFactory,
			Session session, int from_id) {
		Criteria cr = session.createCriteria(Relation.class);
		Criterion from = Restrictions.eq("inviting", from_id);
		UserMethods um = new UserMethods();
		cr.add(from);
		@SuppressWarnings("unchecked")
		List<Relation> rels = cr.list();
		List<User> users = new ArrayList<User>();
		
		for(Relation r: rels){
			users.add(um.id_to_user(sessionFactory, session, r.getInvited()));
		}
		return users;
	}

	@Override
	public List<User> findRelationByTo(SessionFactory sessionFactory,
			Session session, int to_id) {
		Criteria cr = session.createCriteria(Relation.class);
		Criterion to = Restrictions.eq("invited", to_id);
		cr.add(to);
		UserMethods um = new UserMethods();
		cr.add(to);
		@SuppressWarnings("unchecked")
		List<Relation> rels = cr.list();
		List<User> users = new ArrayList<User>();
		
		for(Relation r: rels){
			users.add(um.id_to_user(sessionFactory, session, r.getInviting()));
		}
		return users;
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Relation> findRelationFromTo(SessionFactory sessionFactory,
			Session session, int from_id, int to_id) {
	Criteria cr = session.createCriteria(Relation.class);
		
		Criterion from = Restrictions.eq("inviting", from_id);
		Criterion to = Restrictions.eq("invited", to_id);
	
		LogicalExpression andExp = Restrictions.and(from, to);
		cr.add(andExp);
		
		return cr.list();
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Relation> findRelationToFrom(SessionFactory sessionFactory,
			Session session, int from_id, int to_id) {
	Criteria cr = session.createCriteria(Relation.class);
		
		Criterion from = Restrictions.eq("inviting", to_id);
		Criterion to = Restrictions.eq("invited", from_id);
	
		LogicalExpression andExp = Restrictions.and(from, to);
		cr.add(andExp);
		
		return cr.list();
	}

	@Override
	public List<User> listAllFriends(SessionFactory sessionFactory,
			Session session, int user_id) {
		List<User> friendList = new ArrayList<User>();
		//UserMethods um = new UserMethods();
		List<User> firstList = findRelationByFrom(sessionFactory, session, user_id);
		List<User> secondList = findRelationByTo(sessionFactory, session, user_id);
		List<User> List1 = new ArrayList<User>(firstList);
		List1.addAll(secondList);
		friendList.addAll(new ArrayList<User>(new LinkedHashSet<User>(List1)));
		return friendList;
		
	}
	
	

}
